#include "epollFunc.h"
#include "head.h"
#include "transFile.h"

#include <54func.h>

void clientPrint(const char *userName, const char *curPath){
    char printbuf[100] = {0};
    printf("%s\n", curPath);
    sprintf(printbuf, "%s%s%s", userName, "@Netdisk:", "$ ");
    printf("%s", printbuf);
    fflush(stdout);
}

int main(int argc, char **argv){
    // ./client 192.168.0.69 1234
    ARGS_CHECK(argc, 3);
    int sockFd = socket(AF_INET, SOCK_STREAM, 0);
    int ret = -1;
    int reuse = 1;
    ret = setsockopt(sockFd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
    ERROR_CHECK(ret, -1, "setsockopt");

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(argv[1]);
    addr.sin_port = htons(atoi(argv[2]));

    struct epoll_event readySet[10];
    int epfd = epoll_create(1);

    train_t train;
    logMsg_t logMsg;
    char tmpUser[20] = {0};
    char tmpPasswd1[30] = {0};
    char tmpPasswd2[30] = {0};
    int input = 0;
    int closeCode = 32;
    char cmdStr[100];
    char *cmdStrArr[] = {0};
    int cmdStrNum = 0;

login_begin:
    system("clear");
    printf("1: 注册请按1\n2: 登录请按2\n");
    bzero(&input, sizeof(input));
    scanf("%d", &input);
    if(1 == input){
        bzero(&tmpUser, sizeof(tmpUser));
        bzero(&tmpPasswd1, sizeof(tmpPasswd1));
        bzero(&tmpPasswd2, sizeof(tmpPasswd2));
        printf("请输入注册账号\n");
        scanf("%s", tmpUser);
        printf("请输入注册密码\n");
        scanf("%s", tmpPasswd1);
        printf("请再次输入注册密码\n");
        scanf("%s", tmpPasswd2);
        if(0 == strcmp(tmpPasswd1, tmpPasswd2)){
            sockFd = socket(AF_INET, SOCK_STREAM, 0);
            ret = connect(sockFd, (struct sockaddr *)&addr, sizeof(addr));
            ERROR_CHECK(ret, -1, "connect");
            printf("connect successful\n");
            bzero(&train, sizeof(train_t));
            train.code = REGISTER_APPLY;
            ret = send(sockFd, &train, sizeof(train_t), MSG_NOSIGNAL);//发送注册申请
            ERROR_CHECK(ret, -1, "send");
        }
        else{
            printf("两次输入的密码不一致，请重新选择\n");
            sleep(1);
            //char ch;while((ch = getchar()) != '\n' && ch != EOF);//刷新缓冲区
            fflush(stdout);
            goto login_begin;
        }
    }
    else if(2 == input){
        //登录
        bzero(&tmpUser, sizeof(tmpUser));
        bzero(&tmpPasswd1, sizeof(tmpPasswd1));
        printf("请输入账号\n");
        scanf("%s", tmpUser);
        printf("请输入密码\n");
        scanf("%s", tmpPasswd1);

        bzero(&logMsg, sizeof(logMsg_t));
        memcpy(logMsg.usrName, tmpUser, strlen(tmpUser));
        memcpy(logMsg.usrPasswd, tmpPasswd1, strlen(tmpPasswd1));

        sockFd = socket(AF_INET, SOCK_STREAM, 0);
        ret = connect(sockFd, (struct sockaddr *)&addr, sizeof(addr));
        ERROR_CHECK(ret, -1, "connect");
        printf("connect successful\n");
        bzero(&train, sizeof(train_t));
        train.code = LOGIN_APPLY;
        //printf("frist send train.code = %d\n", train.code);
        ret = send(sockFd, &train, sizeof(train_t), MSG_NOSIGNAL);//发送登录申请
        //printf("ret = %d\n", ret);
        ERROR_CHECK(ret, -1, "send");
    }
    else{
        printf("输入错误，请重新输入\n");
        sleep(1);
        fflush(stdout);
        goto login_begin;
    }

    epollAdd(epfd, sockFd, EPOLLIN);
    epollAdd(epfd, 0, EPOLLIN);
    while(1){
        int readyNum = epoll_wait(epfd, readySet, 10, -1);
        for(int i = 0; i < readyNum; ++i){
            if(readySet[i].events == EPOLLIN && readySet[i].data.fd == sockFd){
                //服务端信息
                bzero(&train, sizeof(train_t));
                ret = recv_once(sockFd, &train, sizeof(train_t));//是否需要重连
                printf("第一次收到服务端train.code = %d\n", train.code);
                if(ret < 0){
                    //重新连接
                    close(sockFd);
                    epollDel(epfd, sockFd, EPOLLIN);
                    printf("client is reconnecting!\n");
                    ret = connect(sockFd, (struct sockaddr *)&addr, sizeof(addr));
                    ERROR_CHECK(ret, -1, "connect");
                    printf("reconnect successful\n");
                    epollAdd(epfd, sockFd, EPOLLIN);
                }
                //printf("frist recv train.code = %d\n", train.code);
                if(CLOSE_CONNECT == train.code){
                    //客户端异常退出了
                    close(sockFd);
                    epollDel(epfd, sockFd, EPOLLIN);
                    printf("client is exit!\n");
                    exit(0);
                }
                else if(REGISTER_APPLY == train.code){
                    //注册
                    printf("服务端成功连接\n");
                    //客户端成功收到train.code，发送账号和密码
                    train.length = sizeof(tmpUser);
                    memcpy(train.data, tmpUser, train.length);
                    ret = send(sockFd, &train, sizeof(train_t), MSG_NOSIGNAL);//发送账号
                    ERROR_CHECK(ret, -1, "send account");
                    printf("send account\n");
                    
                    bzero(&train.length,sizeof(train.length));
                    bzero(train.data,sizeof(train.data));
                    train.length = sizeof(tmpPasswd1);
                    memcpy(train.data, tmpPasswd1, train.length);
                    ret = send(sockFd, &train, sizeof(train_t), MSG_NOSIGNAL);//发送密码
                    ERROR_CHECK(ret, -1, "send passwd");
                    printf("send passwd\n");
                }
                else if(REGISTER_OK == train.code){
                    //注册成功
                    printf("恭喜,注册成功!\n");
                    sleep(1);
                    goto login_begin;
                }
                else if(REGISTER_FAID == train.code){
                    //已有该用户,注册失败
                    printf("server work.c switch send 已有该用户,注册失败!\n");
                    bzero(&logMsg, sizeof(logMsg_t));
                    bzero(&train, sizeof(train_t));
                    memcpy(&train.code, &closeCode, sizeof(closeCode));
                    printf("train.code = %d\n", train.code);
                    ret = send(sockFd, &train, sizeof(train_t), MSG_NOSIGNAL);
                    ERROR_CHECK(ret, -1, "send close signum");
                    printf("send close msg\n");
                    epollDel(epfd, sockFd, EPOLLIN);
                    close(sockFd);
                    sleep(1);
                    goto login_begin;
                }
                
                else if(LOGIN_APPLY == train.code){
                    printf("服务端成功连接\n");
                    //客户端成功收到train.code，发送账号和密码
                    train.length = sizeof(tmpUser);
                    memcpy(train.data, tmpUser, train.length);
                    ret = send(sockFd, &train, sizeof(train_t), MSG_NOSIGNAL);//发送账号
                    ERROR_CHECK(ret, -1, "send account");
                    //printf("send account\n");
                    
                    bzero(&train.length,sizeof(train.length));
                    bzero(train.data,sizeof(train.data));
                    train.length = sizeof(tmpPasswd1);
                    memcpy(train.data, tmpPasswd1, train.length);
                    ret = send(sockFd, &train, sizeof(train_t), MSG_NOSIGNAL);//发送密码
                    ERROR_CHECK(ret, -1, "send passwd");
                    //printf("send passwd\n");
                }
                else if(LOGIN_OK == train.code){
                    printf("登录成功!\n");
                    //还要接收一个当前路径 "zhangsan@Netdisk:~Netdisk/zhangsan$ "
                    memcpy(logMsg.clientPath, train.data, train.length);
                    clientPrint(logMsg.usrName, logMsg.clientPath);
                }
                else if(LOGIN_FAID == train.code){
                    printf("账户名或密码错误, 登录失败!\n");
                    bzero(&train, sizeof(train_t));
                    memcpy(&train.code, &closeCode, sizeof(closeCode));
                    printf("train.code = %d\n", train.code);
                    ret = send(sockFd, &train, sizeof(train_t), MSG_NOSIGNAL);
                    ERROR_CHECK(ret, -1, "send close signum");
                    printf("send close msg\n");
                    epollDel(epfd, sockFd, EPOLLIN);
                    close(sockFd);
                    sleep(1);
                    goto login_begin;
                }
                
                else if(LS_OK == train.code){}
                else if(LS_FAID == train.code){   
                }
                
                else if(CD_OK == train.code){}
                else if(CD_FAID == train.code){
                    printf("目录%s不存在, 请重新输入\n", train.data);
                }
                
                else if(PWD_APPLY == train.code){}
                else if(PWD_OK == train.code){
                    bzero(&logMsg.clientPath, strlen(logMsg.clientPath));
                    memcpy(logMsg.clientPath, train.data, strlen(train.data));
                }
                else if(PWD_FAID == train.code){
                    printf("pwd参数错误!\n");
                }
                
                else if(PUTS_OK == train.code){}
                else if(PUTS_FAID == train.code){}
                
                else if(GETS_OK == train.code){}
                else if(GETS_FAID == train.code){}

                else if(RM_OK == train.code){}
                else if(RM_FAID == train.code){}

                else if(MKDIR_OK == train.code){
                    printf("创建文件夹成功!\n");
                }
                else if(MKDIR_FAID == train.code){
                    printf("创建文件夹失败!\n");
                }

                else if(RMDIR_OK == train.code){}
                else if(RMDIR_FAID == train.code){}
            }
            else if(readySet[i].events == EPOLLIN && readySet[i].data.fd == 0){
                //解析命
                int ch;while((ch = getchar()) != '\n' && ch != EOF);//刷新缓冲区
                bzero(&cmdStr, strlen(cmdStr));
                fgets(cmdStr, 100, stdin);
                //cmdStrArr[0] = "pwd", "ls", "cd"
                //cmdStrArr[1] =              "dir1"
                //train.code = XX_APPLY
                memcpy(train.data, cmdStr, strlen(cmdStr));
                printf("客户端输入命令： %s\n", train.data);
                parseStr(cmdStr, cmdStrArr, &cmdStrNum, &train);
                printf("train.code = %d\n", train.code);
                
                if(LS_APPLY == train.code){
                    //发送ls等命令字符串
                    printf("客户端输入命令: ls\n");
                    ret = send(sockFd, &train, sizeof(train_t), MSG_NOSIGNAL);
                    ERROR_CHECK(ret, -1, "send");
                }
                else if(CD_APPLY == train.code){
                    //发送cd等命令字符串
                    printf("客户端输入命令: pwd\n");
                    ret = send(sockFd, &train, sizeof(train_t), MSG_NOSIGNAL);
                    ERROR_CHECK(ret, -1, "send");
                }
                else if(PWD_APPLY == train.code){
                    //发送pwd等命令字符串
                    printf("客户端输入命令: pwd\n");
                    ret = send(sockFd, &train, sizeof(train_t), MSG_NOSIGNAL);
                    ERROR_CHECK(ret, -1, "send");
                }
                else if(PUTS_APPLY == train.code){}
                else if(GETS_APPLY == train.code){}
                else if(RM_APPLY == train.code){}
                else if(MKDIR_APPLY == train.code){
                    printf("客户端输入命令: %s\n", train.data);
                    ret = send(sockFd, &train, sizeof(train_t), MSG_NOSIGNAL);
                    ERROR_CHECK(ret, -1, "send");
                }
                else if(RMDIR_APPLY == train.code){}
            }
            clientPrint(logMsg.usrName, logMsg.clientPath);
        }
    }
    return 0;
}